package com.gxa.community.admin.service.bill.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gxa.community.admin.mapper.bill.BillMapper;
import com.gxa.community.admin.service.bill.BillService;
import com.gxa.community.core.pojo.domain.Bill;
import com.gxa.community.core.pojo.dto.bill.BillDto;
import com.gxa.community.core.pojo.dto.bill.storage.BillStorageDto;
import com.gxa.community.core.pojo.vo.admin.bill.BillVo;
import com.gxa.community.core.pojo.vo.admin.bill.expand.BillVoE;
import com.gxa.community.core.utils.LittleUtils;
import com.gxa.community.core.utils.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author juran
 * @since 2022-07-19
 */
@Service
public class BillServiceImpl extends ServiceImpl<BillMapper, Bill> implements BillService {

    @Autowired
    BillMapper billMapper;

    /**
     * 查询账单信息
     * @param billDto
     * @param cpage
     * @param size
     * @return
     */
    @Override
    public R queryBill(BillDto billDto,
                       long cpage,
                       long size) {

        QueryWrapper<Bill> wrapper = new QueryWrapper<>();
        if (billDto.getNo() != null && !Objects.equals(billDto.getNo(), "")) {
            wrapper.eq("no", billDto.getNo());
        }
        if (billDto.getOrderNo() != null) {
            wrapper.eq("order_no", billDto.getOrderNo());
        }
        if (billDto.getType() != null) {
            wrapper.eq("type", billDto.getType());
        }
        if (billDto.getStartTime() != null && billDto.getEndTime() != null) {
            wrapper.between("time", billDto.getStartTime(), billDto.getEndTime());
        }
        //如果有起始时间那么，结束时间为当前，只有结束时间，必须有起始时间。
        if (billDto.getStartTime() != null) {
            wrapper.between("time", billDto.getStartTime(), System.currentTimeMillis());
        }
        if (billDto.getStatus() != null) {
            wrapper.eq("status", billDto.getStatus());
        }

        Page<Bill> page = new Page<>(cpage,size);
        //查询所有支付账单
        Page<Bill> billPage = billMapper.selectPage(page, wrapper);

        //将所有数据转换成VO
        BillVo billVo = new BillVo();
        //将数据给与vo
        billVo.setList(billPage.getRecords().stream().map(
                p -> {
                    return new BillVoE()
                            .setCommission(p.getCommission())
                            .setNo(p.getNo())
                            .setOrderAmount(p.getOrderAmount())
                            .setTime(p.getTime())
                            .setType(p.getType())
                            .setStatus(p.getStatus())
                            .setOrderNo(p.getOrderNo())
                            .setRemark(p.getRemark());
                }
        ).collect(Collectors.toList()));
        //统计所有订单金额
        billPage.getRecords().forEach(p -> {
            Double amount = billVo.getOrderAmountStatistics();
            billVo.setOrderAmountStatistics(amount += p.getOrderAmount());
        });
        //统计1金额|佣金
        QueryWrapper<Bill> wrappera = new QueryWrapper<>();
        wrappera.select("IFNULL(sum(order_amount),0) as amount," +
                        "IFNULL(sum(commission),0) as commission")
                .eq("type", 1);
        Map<String, Object> mapa = getMap(wrappera);
        //统计2退款金额|扣除佣金
        QueryWrapper<Bill> wrapperb = new QueryWrapper<>();
        wrapperb.select("IFNULL(sum(order_amount),0) as amount," +
                        "IFNULL(sum(commission),0) as commission")
                .eq("type", 2);
        Map<String, Object> mapb = getMap(wrapperb);
        billVo.setOrderAmountOutStatistics((Double) mapb.get("amount"));
        //统计佣金支出: 佣金支出 = 全部佣金 - 退款扣除佣金
        billVo.setOrderCommissionStatistics((Double) mapa.get("commission") - (Double) mapb.get("commission"));
        //统计实际收入 = 所有订单金额 - 退款金额 - 佣金支出
        billVo.setOrderClinchStatistics(billVo.getOrderAmountStatistics() -
                billVo.getOrderAmountOutStatistics() -
                billVo.getOrderCommissionStatistics());

        HashMap<Object, Object> hashMap = new HashMap<>();
        hashMap.put("total",page.getTotal());
        hashMap.put("pages",page.getPages());
        hashMap.put("pageSize",page.getSize());
        hashMap.put("currentPage",page.getCurrent());
        hashMap.put("list",billVo);

        return R.ok().put("data",hashMap);
    }

    /**
     * 标记账单信息，进行审核
     * @param billDto
     * @return
     */
    @Override
    public R editBill(BillDto billDto) {
        UpdateWrapper<Bill> ew = new UpdateWrapper<>();
        ew.lambda().set(Bill::getStatus,billDto.getStatus())
                        .set(Bill::getRemark,billDto.getRemarks())
                                .eq(Bill::getNo,billDto.getNo());

        boolean update = update(ew);
        System.out.println("是否修改成功" + update);
        return null;
    }

    /**
     * 添加对账记录
     * @param billStorageDto
     * @return
     */
    @Override
    public R addBillInfo(BillStorageDto billStorageDto) {
        //TODO 账单账号流水号

        boolean save = save(new Bill()
                .setNo(billStorageDto.getNo())
                .setType(billStorageDto.getType())
                .setOrderNo(billStorageDto.getOrderNo())
                .setOrderAmount(billStorageDto.getOrderAmount())
                .setCommission(billStorageDto.getCommission())
                .setTime(billStorageDto.getTime())
                //账单流水号
                .setNo(LittleUtils.generateNo(16)));

        return save ? R.ok("添加成功") : R.error("添加失败");
    }
}
